import {Router} from "vue-router";
import {deepClone, uuid} from "@/utils";
import {useAppStore, useAuthStore} from "@/stores";
import {DefaultLayout} from "@/components/index.ts";
import type {SysMenu} from "@/api/menu/types.ts";
import type {RouteItem} from "@/types/router.ts";

const whiteList = ['/login']
const modules = import.meta.glob('/src/views/**/index.vue')
/**
 * 设置路由守卫
 *
 * 此函数用于在Vue Router实例上设置全局守卫，处理页面加载前的逻辑，如进度条、文档标题设置、权限验证等
 * 它还处理了登录状态下的路由跳转逻辑以及登录白名单的校验
 *
 * @param router Vue Router实例，用于设置守卫
 */
export const setupRouterGuard = (router: Router) => {
    // 页面加载前的守卫
    router.beforeEach(async (to) => {
        // 启动进度条
        window.$loadingBar?.start()

        // 设置文档标题
        if (to.meta.title) {
            document.title = `${to.meta.title} - ${import.meta.env.VITE_APP_TITLE}`
        }

        // 使用authStore来管理登录状态和权限
        const authStore = useAuthStore();

        // 已登录状态下的处理逻辑
        if (authStore.isLogin()) {
            const appStore = useAppStore();
            // 如果用户尚未获取路由，添加动态路由
            if (!authStore.hasGetRoutes) {
                await addDynamicRoutes(authStore, router);
                authStore.hasGetRoutes = true;
                // 重定向到原路径
                return {
                    path: to.fullPath,
                    replace: true,
                    query: to.query,
                    hash: to.hash,
                }
            } else if (to.matched.length === 0) {
                // 如果没有匹配到任何组件，跳转到404页面
                return {path: '/404'}
            }

            // 检查权限，如果没有相应权限，跳转到403页面
            if (!authStore.hasPermission(to.meta.permissionCode)) {
                return {path: '/403'}
            }

            // 处理查询参数，添加随机标识符
            if (!to.query.r) {
                let newQuery = deepClone(to.query);
                await router.replace({path: to.path, query: {...newQuery, r: uuid()}})
            }
            appStore.addTab(getComponentName(to), to.path, to.meta, to.query)
            // 如果目标路径是登录页面，重定向到主页
            return to.path === '/login' ? {path: '/'} : true;
        } else {
            // 未登录状态下的处理逻辑，检查是否在白名单内
            return whiteList.includes(to.path) ? true : {path: '/login', query: {...to.query, redirect: to.path}};
        }
    })

    // 页面加载后的守卫
    router.afterEach(() => {
        // 结束进度条
        window.$loadingBar?.finish()
    })

    // 路由错误处理
    router.onError((error) => {
        // 显示错误信息
        window.$message?.error(error.message)
        // 进度条错误提示
        window.$loadingBar?.error()
    })
}

const getComponentName = (route) => {
    const matched = route.matched;
    const currentComponent = matched[matched.length - 1].components!.default;
    return currentComponent.name;
}

const addDynamicRoutes = async (authStore: any, router: Router) => {
    const menus = await authStore.getDynamicMenus();
    menus.forEach((menu: SysMenu) => {
        menu.permissionCode
        && !router.hasRoute(menu.permissionCode)
        && router.addRoute(resolveMenu(0, menu))
    })
}

const resolveMenu = (level: number, menu: SysMenu, parentPath: string = ''): RouteItem => {
    if (menu.menuType === 0) {
        return {
            name: menu.permissionCode,
            path: menu.menuPath,
            meta: {
                title: menu.menuName,
                icon: menu.menuIcon,
                permissionCode: menu.permissionCode
            },
            component: DefaultLayout,
            children: menu.children?.map(e => resolveMenu(level + 1, e, menu.menuPath))
        } as RouteItem
    } else if (menu.menuType === 1) {
        if (level !== 0) {
            return {
                name: menu.permissionCode,
                path: `${parentPath}${menu.menuPath}`,
                meta: {
                    title: menu.menuName,
                    icon: menu.menuIcon,
                    permissionCode: menu.permissionCode
                },
                component: modules[`/src/views${menu.componentPath}/index.vue`]
            } as RouteItem
        } else {
            return {
                name: menu.permissionCode,
                path: '/',
                component: DefaultLayout,
                children: [
                    {
                        path: `${menu.menuPath}`,
                        meta: {
                            title: menu.menuName,
                            icon: menu.menuIcon,
                            permissionCode: menu.permissionCode
                        },
                        component: modules[`/src/views${menu.componentPath}/index.vue`]
                    } as RouteItem
                ]
            }
        }
    }
    return {} as RouteItem
}
